//
//  TCGirdView.swift
//  onemeetingmac
//
//  Created by 张衡 on 2019/12/17.
//  Copyright © 2019 onemeeting. All rights reserved.
//

import Foundation

enum GalleryTpye {
    case gird
    case speaker
    case shareScreen
}
@objc protocol TCGirdViewDelegate {
    func trtcGird_onClick(girdView:TCGirdView,row:Int,view:TCVideoView,event:NSEvent)
    func trtcGird_donbleClick(girdView:TCGirdView,row:Int,view:TCVideoView,event:NSEvent)
    func trtcGird_mouseEnter(girdView:TCGirdView,row:Int,view:TCVideoView)
    func trtcGird_mouseExit(girdView:TCGirdView,row:Int,view:TCVideoView)
    func trtcGird_mute(girdView:TCGirdView,row:Int,view:TCVideoView,btn:ZHButton)
    func trtcGird_more(girdView:TCGirdView,row:Int,view:TCVideoView,btn:ZHButton)
    func trtcGird_hand(girdView:TCGirdView,row:Int,view:TCVideoView,icon:KIcon)
}



class TCGirdView: NSView {
    
    var infoList    :[UserInfo]    = []
    var viewList    :[TCVideoView] = []
    var subInfoList :[UserInfo]    = []
    var subViewList :[TCVideoView] = []
    
    
    //列
    var kGvnum = CGFloat(2)
    //行
    var kGhnum = CGFloat(2)
    
    var isSding:Bool {
        return Td.sh().sd.isSding
    }
    
    var isPic2pic:Bool = false
    
    var lastMultipliedBy:CGFloat = 0.2
    
    var specifyUid:String?
    
    var touchDelegate:TCGirdViewDelegate?
    
    var hasSpalt:Bool = false {
        didSet {
            if self.mode == .shareScreen {
                let multipliedBy = hasSpalt ? 0:self.lastMultipliedBy
                self.sdDrop.isHidden = hasSpalt
                self.sdDrop.isEnable = !hasSpalt
                self.smallconner.isHidden = true
                self.conner.isHidden = false
                self.conner.snp.remakeConstraints { (make) in
                    make.width.equalToSuperview().multipliedBy(multipliedBy)
                    make.centerY.height.right.equalToSuperview()
                }
            }
        }
    }
    
    override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
    }
    
    convenience init(infoList:[UserInfo]) {
        self.init()
        self.infoList = infoList
        self.kGvnum = CGFloat(2)
        self.kGhnum = CGFloat(2)
        self.setupUI()
    }
    
    var maxSubWidth:CGFloat {
        get {
            return self.frame.width-kMinSubRomteWidth
        }
    }
    
    var minSubWidth:CGFloat {
        get {
            return kMinSubRomteWidth+20
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    var isFullScreen:Bool = false {
        didSet {
            self.reloadMode()
        }
    }
    
    var mode:GalleryTpye = .gird{
        didSet{
            switch mode {
            case .speaker:
                self.smallconner.isHidden = true
                self.sdDrop.isEnable = false
            case .shareScreen:
                self.sdDrop.isHidden = false
                self.sdDrop.isEnable = true
            default:
                self.smallconner.isHidden = true
                self.sdDrop.isEnable = false
            }
            self.reloadMode()
       }
   }
   
    func setMode(c:Int) -> (Int,Int) {
        var h:Int = 1
        var v:Int = 1
        switch c {
        case 1:
            h = 1
            v = 1
        case 2:
            h = 2
            v = 1
        case 3,4:
            h = 2
            v = 2
        case 5,6:
            h = 3
            v = 2
        case 7,8,9:
            h = 3
            v = 3
        case 10..<Int.max:
            h = 5
            v = 5
        default:
            break
        }
        return (h,v)
    }

    
    func setupUI() {
        
        self.addSubview(conner)
        conner.snp.makeConstraints { (make) in
            make.width.equalToSuperview().offset(0)
            make.centerY.height.equalToSuperview()
            make.right.equalToSuperview()
        }
        
        self.addSubview(subconner)
        subconner.snp.makeConstraints { (make) in
            make.width.equalToSuperview().offset(0)
            make.centerY.height.equalToSuperview()
            make.right.equalToSuperview()
        }
        
        self.addSubview(sdDrop)
        sdDrop.snp.makeConstraints { (make) in
            make.width.equalTo(500)
            make.right.equalTo(conner.snp.left).offset((500-10)/2)
            make.centerY.equalToSuperview()
            make.height.equalToSuperview()
        }
        
        conner.addSubview(smallconner)
        smallconner.snp.makeConstraints { (make) in
            make.top.centerX.width.equalToSuperview()
            make.height.equalTo(140)
        }
        
        smallconner.addSubview(topsmallconner)
        topsmallconner.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        
        self.addSubview(sdScreen)
        sdScreen.snp.makeConstraints { (make) in
            make.right.equalTo(smallconner.snp.left).offset(-10)
            make.left.centerY.height.equalToSuperview()
        }
    }
    lazy var subconner: NSView = {
        let view = NSView()
        view.wantsLayer = true
        view.layer?.backgroundColor = color_gray(0).cgColor
        view.isHidden = true
        return view
    }()
    
    lazy var conner: NSView = {
        let view = NSView()
        view.wantsLayer = true
        view.layer?.backgroundColor = color_gray(0).cgColor
        return view
    }()
    
    
    lazy var topsmallconner: NSView = {
        let view = NSView()
        view.wantsLayer = true
        view.layer?.backgroundColor = color_gray(210).cgColor
        view.isHidden = true
        return view
    }()
    
    lazy var smallconner: NSView = {
        let view = NSView()
        view.wantsLayer = true
        view.layer?.backgroundColor = color_gray(80).cgColor
        view.isHidden = true
        return view
    }()
    
    func remove(stringList:[String]) {
        for (_,value) in stringList.enumerated() {
            let firstIndex = self.infoList.firstIndex(where: {$0.userId == value})
            let firstInfo = self.infoList.first(where: {$0.userId == value})
            if let first = firstIndex, let info = firstInfo{
                if info.streamType == .sub {
                    TXLiteManager.shared().stopRemoteSubStreamView(userId: value)
                }else {
                    if value.isCurret() == true {
                        TXLiteManager.shared().stopLocalPreview()
                    }else {
                        TXLiteManager.shared().stopRemoteView(userId: value)
                    }
                }
                self.infoList.remove(at: first)
                self.viewList.remove(at: first)
            }
        }
    }
    
    
    func pic2picSet(info:UserInfo,index:Int?) {
        if self.subInfoList[safe:1] != nil {
            self.subInfoList[1] = info
            self.reloadPart(inx: 1)
        }else {
            self.addNewSub(uInfo: info,inx: nil)
        }
    }
    
    func pic2picInitOrFocusChange() {
        let focusInfo = self.infoList.first(where: {$0.userId?.isFocusId() == true})
        if let focus = focusInfo {
            self.pic2picSet(info: focus, index: nil)
        }else {
            let subID = self.infoList.first(where: {$0.userId == self.subInfoList[safe:0]?.userId})
            if let sub = subID {
                self.pic2picSet(info: sub, index: nil)
            }
        }
        
    }
    
    func enterPic2pic() {
        self.isPic2pic = !self.isPic2pic
        if self.isPic2pic {
            self.pic2picInitOrFocusChange()
        }else {
            if self.subInfoList.count > 1 {
                self.subInfoList.removeLast()
                self.subViewList.removeLast()
            }
        }
        self.reloadMode()
        self.reloadPart(inx: 1)
    }
    
    func inFullForm(first object:String?) {
        if object == nil {
            self.reloadMode()
        }else {
            let first = self.infoList.firstIndex(where: {$0.userId == object!})
            if let row = first {
                self.inFullForm(of: row)
            }
        }
    }
    
    
    func inFullForm(of row:Int) {
        let view = self.viewList[row]
        self.viewList.forEach { (videoView) in
            videoView.isHidden = view != videoView
        }
        view.snp.remakeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        self.specifyUid = self.infoList[row].userId
    }
    
    func enterScreen(infoList:[UserInfo]) {
        self.subconner.isHidden = false
        self.conner.isHidden = true
        self.showStreamView(infoList: infoList)
    }
    
    func exitScreen() {
        self.subconner.isHidden = true
        self.conner.isHidden = false
        self.reloadData(noLocal: false)
    }
    
    
    func showStreamView(infoList:[UserInfo]) {
        self.subInfoList.removeAll()
        self.subViewList.forEach { (info) in
            info.removeFromSuperview()
        }
        self.subViewList.removeAll()
        
        for (_,value) in infoList.enumerated() {
            let opIndex = value.streamType == .sub ? 0:nil
            self.addNewSub(uInfo: value,inx: opIndex)
        }
        self.reloadData(noLocal: false)
    }
    
    func reViewListForm(infoList:[UserInfo]) {
        TXLiteManager.shared().stopAllRemoteView()
        TXLiteManager.shared().stopLocalPreview()
        self.infoList.removeAll()
        self.viewList.forEach { (view) in
            view.removeFromSuperview()
        }
        self.viewList.removeAll()
        
        let sub = infoList.contains { (info) -> Bool in
            return info.streamType == .sub
        }
        for (_,value)  in infoList.enumerated() {
            if sub == true {
                let opIndex = value.streamType == .sub ? 0:nil
                self.addNew(uInfo: value,inx: opIndex)
            }else {
                let opIndex = value.userId?.isCurret() == true ? 0:nil
                self.addNew(uInfo: value,inx: opIndex)
            }
        }
        self.reloadData()
    }
   
    func remove(inx:Int) {
        if self.viewList.count >= inx+1{
            let view = self.viewList[inx]
            view.removeFromSuperview()
            self.viewList.remove(at: inx)
            self.infoList.remove(at: inx)
            self.reloadMode()
        }
    }
    
    
    func addNewSub(uInfo:UserInfo,inx:Int?=nil)  {
        let view = TCVideoView.init(data: uInfo, delegate: self)
        view.backgroundColor = NSColor.black
        self.subconner.addSubview(view)
        
        if inx == nil {
            self.subViewList.append(view)
            self.subInfoList.append(uInfo)
        }else {
            self.subViewList.insert(view, at: inx!)
            self.subInfoList.insert(uInfo, at: inx!)
        }
        self.reloadMode()
    }
    
    func addNew(uInfo:UserInfo,inx:Int?=nil)  {
         let view = TCVideoView.init(data: uInfo, delegate: self)
         view.backgroundColor = NSColor.black
         view.isSelect = uInfo.userId?.isFocusId()==true
         self.conner.addSubview(view)
         
         if inx == nil {
             self.viewList.append(view)
             self.infoList.append(uInfo)
         }else {
             self.viewList.insert(view, at: inx!)
             self.infoList.insert(uInfo, at: inx!)
         }
         self.reloadMode()
    }
    
    
    func enterScreen(focusID:String?) {
        self.viewList.forEach { (vdView) in
            if vdView.data?.userId != focusID {
              vdView.removeFromSuperview()
            }
        }
        self.viewList.removeAll { (videoView) -> Bool in
            return videoView.data?.userId != focusID
        }
        
        self.infoList.removeAll { (info) -> Bool in
            return info.userId != focusID
        }
    }
    
    
    
    func removeSub() {
        self.viewList.forEach { (vdView) in
            vdView.removeFromSuperview()
        }
        self.viewList.removeAll()
        self.infoList.removeAll()
    }
    
    func checkStatus() {
        self.backInit()
        let index = infoList.firstIndex { (info) -> Bool in
            return (info.userId?.isFocusId()==true)
        }
        if index != nil && self.viewList.count>=(index!+1) {
            if self.viewList.count>=(index!+1)  {
                let able = self.viewList[index!]
                able.isSelect = true
            }
        }
    }
    
    func reloadPreview(infoList:[UserInfo],viewList:[TCVideoView],noLocal:Bool) {
        if viewList.count == infoList.count {
            for (inx,view) in viewList.enumerated() {
                let info = infoList[inx]
                if let uid = info.userId {
                    view.data = info
                    if info.streamType == .big || info.streamType == .small {
                        if uid.isCurret() {
                            if Td.sh().lc.isVdOpen == true {
                                if noLocal == false{
                                    TXLiteManager.shared().stopLocalPreview()
                                }
                                //异步加载，解决有时关闭本地流，再次打开视频流，不显示视频问题
                                DispatchQueue.main.async {
                                    TXLiteManager.shared().startLocalPreview(view: view.videoView)
                                    TXLiteManager.shared().setLocalViewFillMode(mode: TRTCVideoFillMode.fit)
                                }
                            }else {
                                TXLiteManager.shared().stopLocalPreview()
                            }
                            let isMute = MTNot.getLocalMute()
                            if isMute == false {
                                TXLiteManager.shared().startLocalAudio()
                            }else {
                                TXLiteManager.shared().stopLocalAudio()
                            }
                        }else {
                            if info.isVdOpen == true {
                                TXLiteManager.shared().stopRemoteView(userId: uid)
                                TXLiteManager.shared().startRemoteView(userId: uid, view: view.videoView)
                            }else {
                                TXLiteManager.shared().stopRemoteView(userId: uid)
                            }
                        }
                    }else if info.streamType == .sub {
                        if info.isVdOpen == true {
                            TXLiteManager.shared().stopRemoteSubStreamView(userId: uid)
                            TXLiteManager.shared().startRemoteSubStreamView(userId: uid, view: view.videoView)
                        }else {
                            TXLiteManager.shared().stopRemoteSubStreamView(userId: uid)
                        }
                    }
                    
                }
                
            }
        }
    }
    
    //赋值
    func reloadData(noLocal:Bool=false) {
        let infoList = self.isSding ? self.subInfoList:self.infoList
        let viewList = self.isSding ? self.subViewList:self.viewList
        self.reloadPreview(infoList: infoList, viewList: viewList, noLocal: noLocal)
    }
    
    func reloadOnly() {
        var infoList = self.isSding ? self.subInfoList:self.infoList
        Td.sh().usr.remote.forEach { (info) in
            for (index,value) in infoList.enumerated() {
                if value.userId == info.userId {
                    if info.userId?.isCurret() == true {
                        infoList[index].self.isMute = MTNot.getLocalMute()
                    }else {
                        infoList[index].isMute = info.isMute
                    }
                    infoList[index].isHandUp = info.isHandUp
                    infoList[index].isAdc = info.isAdc
                    infoList[index].isVdOpen = info.isVdOpen
                    
                }
            }
        }
    }
    
    /*
     index 如果指定的索引==nil，就全部遍历刷新
     */
    func reloadDataNoVideo(index:Int?=nil) {
        let viewList = self.isSding ? self.subViewList:self.viewList
        let infoList = self.isSding ? self.subInfoList:self.infoList
        self.reloadOnly()
        if infoList.count == viewList.count {
            if let inx = index {
                viewList[inx].data = infoList[inx]
            }else {
                for (inx,view) in viewList.enumerated() {
                    view.data = infoList[inx]
                }
            }
        }
    }
    
    func reloadPart(inx:Int) {
        let infolist = self.isSding ? self.subInfoList:self.infoList
        let viewList = self.isSding ? self.subViewList:self.viewList
        
        if viewList.count>inx,infolist.count>inx {
            let info = infolist[inx]
            let view = viewList[inx]
            guard let uid = info.userId else {
                return
            }
            view.data = info
            if uid.isCurret() {
                if Td.sh().lc.isVdOpen == true {
                    TXLiteManager.shared().stopLocalPreview()
                    TXLiteManager.shared().startLocalPreview(view: view.videoView)
                }
            }else {
                TXLiteManager.shared().stopRemoteView(userId: uid)
                TXLiteManager.shared().startRemoteView(userId: uid, view: view.videoView)
            }
        }
    }
    
    //赋值
    func reloadDataPart(subscripts:[Int],infoList:[UserInfo]) {
        if subscripts == [] {
            for (inx,_) in infoList.enumerated(){
                self.reloadPart(inx: inx)
            }
        }else {
            for (_,inx) in subscripts.enumerated() {
                self.reloadPart(inx: inx)
            }
        }
    }
    
    
    func reloadMode() {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+0.1) {
            self.connerUpdate()
            switch self.mode {
            case .speaker:
                self.reloadSpeakerUI(focusId: 0, visiableVs: self.viewList)
                self.reloadSpeakerUI(focusId: 0, visiableVs: self.subViewList)
            case .gird:
                self.reloadUI(wxView: self.conner, visiableVs: self.viewList)
                self.reloadUI(wxView: self.subconner, visiableVs: self.subViewList)
            case .shareScreen:
                self.reloadSubUI(wxView: self.conner, visiableVs: self.viewList)
                self.reloadSubUI(wxView: self.subconner, visiableVs: self.subViewList)
            }
        }
    }
    
    func connerUpdate() {
        if self.mode == .shareScreen {
            let mins = kMinSubRomteWidth/self.frame.width
            let scale = mins<self.lastMultipliedBy ? lastMultipliedBy:mins
            let mult = self.hasSpalt ? 0:scale
            self.conner.snp.remakeConstraints { (make) in
                make.width.equalToSuperview().multipliedBy(mult)
                make.centerY.height.right.equalToSuperview()
            }
            self.lastMultipliedBy = scale
        }else {
            self.conner.snp.remakeConstraints { (make) in
                make.width.equalToSuperview()
                make.centerY.height.right.equalToSuperview()
            }
        }
        
    }
    
    func reload() {
        self.removeSub()
    }
    
    
    func backInit() {
        for (_,able) in self.viewList.enumerated(){
            able.isSelect = false
        }
    }
    
    //MARK: 切换焦点
    func swapt(focusId:String) {
        self.swaptId(userId: focusId, infoList: self.infoList)
    }
    
    func swapt(from:UserInfo) {
        self.swaptForm(info: from, infoList: self.infoList)
    }
    
    func swaptId(userId:String,to index:Int=1,infoList:[UserInfo]) {
        let indexB = infoList.firstIndex { (info) -> Bool in
            return info.userId==userId
        }
        if let inx = indexB {
            let info = infoList[inx]
            self.swaptForm(info: info, to: index, infoList: infoList)
        }
    }
    
    func swaptForm(info:UserInfo,to index:Int=1,infoList:[UserInfo]) {
        let fromId = info.userId
        if let useridB = fromId {
            let indexB = infoList.firstIndex { (info) -> Bool in
                return info.userId==useridB
            }
            if indexB==index || fromId?.isCurret()==true { return }
            if infoList.count >= 2 {
                if let inxB = indexB {
                    if self.infoList == infoList {
                        self.infoList.swapAt(index, inxB)
                    }else if self.subInfoList == infoList {
                        self.subInfoList.swapAt(index, inxB)
                    }
                    self.reloadDataPart(subscripts: [index,inxB], infoList: infoList)
                    self.reloadDataNoVideo()
                    self.checkStatus()
                }else {
                    if self.infoList == infoList {
                        self.infoList.remove(at: index)
                        self.infoList.insert(info, at: index)
                    }else if self.subInfoList == infoList {
                        self.subInfoList.remove(at: index)
                        self.subInfoList.insert(info, at: index)
                    }
                    self.reloadDataPart(subscripts: [index], infoList: infoList)
                    self.reloadDataNoVideo()
                    self.checkStatus()
                }
            }
            
        }
    }
    
    lazy var sdDrop: SdDrapView = {
        let view = SdDrapView()
        view.hasDrapCursor = true
        view.isEnable = false
        view.draggedClick = { (_,event) in
            self.dragging(view: view,event: event)
        }
        return view
    }()
    
    lazy var sdScreen: NSView = {
        let view = NSView()
        view.wantsLayer = true
        view.layer?.backgroundColor = color_gray(40).cgColor
        return view
    }()
    
    func dragging(view:SdDrapView,event:NSEvent) {
        if self.hasSpalt == false && self.mode == .shareScreen  {
            let selfWidth = self.frame.width
            let minWidth:CGFloat = self.minSubWidth
            let maxWidth:CGFloat = self.maxSubWidth
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {
                let local = event.locationInWindow
                var connerW = selfWidth-(local.x+20)
                connerW = connerW<minWidth ? minWidth:connerW
                connerW = connerW>maxWidth ? maxWidth:connerW
                let multiplied = connerW/selfWidth
                self.conner.snp.remakeConstraints { (make) in
                    make.width.equalToSuperview().multipliedBy(multiplied)
                    make.height.right.centerY.equalToSuperview()
                }
                self.reloadFsUI(wxView: self.conner, visiableVs: self.viewList)
                self.lastMultipliedBy = multiplied            }
        }
    }
    
    func reloadSpeakerUI(focusId:Int=0,visiableVs:[TCVideoView]) {
        let width:CGFloat = 160
        let height:CGFloat = 120
        let space:CGFloat = 20
        
        let big = visiableVs[focusId]
        big.snp.remakeConstraints { (make) in
            make.bottom.centerX.width.equalToSuperview()
            if visiableVs.count>1 && self.isFullScreen == false{
                make.top.equalTo(smallconner.snp.bottom)
            }else {
                make.top.equalTo(0)
            }
        }
        
        self.smallconner.isHidden = true
        var visib = visiableVs
        visib.remove(at: focusId)
        let smallwidth = CGFloat(visib.count)*(width+space)+space
        self.topsmallconner.snp.remakeConstraints { (make) in
            make.height.top.centerX.equalToSuperview()
            make.width.equalTo(smallwidth)
        }
        for (inx,small) in visib.enumerated(){
            small.isHidden = self.isFullScreen
            small.snp.remakeConstraints { (make) in
                make.width.equalTo(width)
                make.height.equalTo(height)
                make.right.equalTo(self.topsmallconner.snp.right).offset(-space-(width+space)*CGFloat(inx))
                make.top.equalTo(10)
                
            }
        }
    }
    
    
    /**
     宽度自适应，高度是宽度的比例，居中显示
     
     - returns: frame
     */
    func rect(wxView:NSView,
             h:Int,
             v:Int,
             count:Int,
             kMinWidth:CGFloat=100,
             kMaxWidth:CGFloat=kMaxSubRomteWidth,
             kSpace:CGFloat=kSubRomteSpace) -> CGRect {
        
        let maxWidth:CGFloat = wxView.frame.size.width-kGirdSpace*CGFloat(count-1)
        var maxHeight:CGFloat = wxView.frame.size.height-kGirdSpace*CGFloat(count-1)
        if count > 1 {
            maxHeight -= KNavgationBarHeight
        }
        let subWidth = maxWidth/CGFloat(h)
        let subHeight = maxHeight/CGFloat(v)
        var wxwidth:CGFloat = subWidth<kMinWidth ? kMinWidth:subWidth
        if kMaxWidth != 0 {
            wxwidth = wxwidth>kMaxWidth ? kMaxWidth:wxwidth
        }
        var wxheight = wxwidth*kSpace
        if wxheight > subHeight {
            wxheight = subHeight
            wxwidth = subHeight/kSpace
        }
        var ytop:CGFloat = 0
        var xleft:CGFloat = 0
        var width:CGFloat = 0
        var height:CGFloat = 0
        if count == 1 {
            ytop = (maxHeight-subWidth*kSpace)/2
            width = subWidth
            height = subWidth*kSpace
        }else {
            if h == 1 {
                ytop = (maxHeight-CGFloat(count)*wxheight)/2
            }else if h > 1 {
                ytop = (maxHeight-CGFloat(v)*wxheight)/2
                xleft = (maxWidth-CGFloat(h)*wxwidth)/2
            }
            ytop += KNavgationBarHeight
            width = wxwidth
            height = wxheight
        }
        
        ytop = ytop < 0 ? 0:ytop
        xleft = xleft < 0 ? 0:xleft
        return CGRect.init(x: xleft, y: ytop, width: width, height: height)
    }
    
    
    
    func reloadFsUI(wxView:NSView,visiableVs:[TCVideoView]) {
        if let uid = self.specifyUid {
            self.inFullForm(first: uid)
            return
        }
        
        wxView.layoutSubtreeIfNeeded()
        let count = visiableVs.count
        let s = self.setMode(c:count)
        let h = s.0,v = s.1
        let maxWidth:CGFloat = wxView.frame.size.width
        for i in 0..<v {
            for j in 0..<h {
                let inx = i*h+j
                if inx>=count {
                    break
                }
                let subView = visiableVs[inx]
                subView.isHidden = false
                
                if visiableVs.count == 1 {
                    let rect = self.rect(wxView: wxView, h: h, v: v, count: visiableVs.count)
                    subView.snp.remakeConstraints { (make) in
                        make.width.equalTo(rect.width)
                        make.height.equalTo(rect.height)
                        make.top.equalTo(rect.origin.y)
                        make.left.equalTo(0)
                    }
                }else {
                    if maxWidth >= kMaxSubRomteWidth*2 && visiableVs.count >= 2 {
                        let rect = self.rect(wxView: wxView, h: h, v: v, count: visiableVs.count)
                        subView.snp.remakeConstraints { (make) in
                            make.width.equalTo(rect.width)
                            make.height.equalTo(rect.height)
                            if i == 0 {
                                make.top.equalTo(rect.origin.y).offset(kGirdSpace)
                            }else {
                                if (inx+1)%h == 1 {
                                     make.top.equalTo(visiableVs[inx-h].snp.bottom).offset(kGirdSpace)
                                }else {
                                    make.top.equalTo(visiableVs[inx-h].snp.bottom).offset(kGirdSpace)
                                }
                               
                            }
                            
                            if (inx+1 >= h*(v-1))  && (count%h != 0){
                                if (inx+1 == h*(v-1)+1) {
                                    let rmleft = (rect.width*CGFloat(h)-(CGFloat(count%h)*rect.width))/2
                                    make.left.equalTo(rect.origin.x+rmleft)
                                }else {
                                    make.left.equalTo(visiableVs[inx-1].snp.right).offset(kGirdSpace)
                                }
                            }else {
                                if j == 0 {
                                    make.left.equalTo(rect.origin.x)
                                }else {
                                    make.left.equalTo(visiableVs[j-1].snp.right).offset(kGirdSpace)
                                }
                            }
                        }
                        
                    }else {
                        let rect = self.rect(wxView: wxView, h: 1, v: visiableVs.count, count: visiableVs.count)
                        subView.snp.remakeConstraints { (make) in
                            if inx == 0 {
                                make.top.equalTo(rect.origin.y)
                            }else {
                                make.top.equalTo(visiableVs[inx-1].snp.bottom).offset(kGirdSpace)
                            }
                            make.centerX.equalToSuperview()
                            make.width.equalTo(rect.width)
                            make.height.equalTo(rect.height)
                        }
                    }
                }
            }
        }
    }
    
    func reloadSubUI(wxView:NSView,visiableVs:[TCVideoView]) {
        if let uid = self.specifyUid {
            self.inFullForm(first: uid)
            return
        }
        
        wxView.layoutSubtreeIfNeeded()
        let count = visiableVs.count
        let s = self.setMode(c:count)
        let h = s.0,v = s.1
        let wxwidth = wxView.frame.size.width/CGFloat(h)
        let wxheight = wxView.frame.size.height/CGFloat(v)
        let rect = self.rect(wxView: wxView, h: h, v: v, count: visiableVs.count,kMaxWidth: 0)
        for i in 0..<v {
            for j in 0..<h {
                let inx = i*h+j
                if inx>=count {
                    break
                }
                let subView = visiableVs[inx]
                subView.isHidden = false
                if visiableVs.count == 1 {
                    subView.snp.remakeConstraints { (make) in
                        make.width.equalTo(wxwidth)
                        make.height.equalTo(wxheight)
                        make.top.equalTo(0)
                        make.left.equalTo(0)
                    }
                }else {
                    subView.snp.remakeConstraints { (make) in
                        make.width.equalTo(rect.width)
                        make.height.equalTo(rect.height)
                        if i == 0 {
                            make.top.equalTo(rect.origin.y)
                        }else {
                            make.top.equalTo(visiableVs[inx-h].snp.bottom).offset(kGirdSpace)
                        }
                        if j == 0 {
                            make.left.equalTo(rect.origin.x)
                        }else {
                            make.left.equalTo(visiableVs[j-1].snp.right).offset(kGirdSpace)
                        }
                    }
                }
            }
        }
    }
    
    func reloadUI(wxView:NSView,visiableVs:[TCVideoView]) {
        if let uid = self.specifyUid {
            self.inFullForm(first: uid)
            return
        }
        
        wxView.layoutSubtreeIfNeeded()
        let count = visiableVs.count
        let s = self.setMode(c:count)
        let h = s.0,v = s.1
        let wxwidth = wxView.frame.size.width/CGFloat(h)
        let wxheight = wxView.frame.size.height/CGFloat(v)
        let rect = self.rect(wxView: wxView, h: h, v: v, count: visiableVs.count,kMaxWidth: 0)
        for i in 0..<v {
            for j in 0..<h {
                let inx = i*h+j
                if inx>=count {
                    break
                }
                let subView = visiableVs[inx]
                subView.isHidden = false
                
                if visiableVs.count == 1 {
                    subView.snp.remakeConstraints { (make) in
                        make.width.equalTo(wxwidth)
                        make.height.equalTo(wxheight)
                        make.top.equalTo(0)
                        make.left.equalTo(0)
                    }
                }else {
                    subView.snp.remakeConstraints { (make) in
                        make.width.equalTo(rect.width)
                        make.height.equalTo(rect.height)
                        if i == 0 {
                            make.top.equalTo(rect.origin.y)
                        }else {
                            if (inx+1)%h == 1 {
                                 make.top.equalTo(visiableVs[inx-h].snp.bottom).offset(kGirdSpace)
                            }else {
                                make.top.equalTo(visiableVs[inx-h].snp.bottom).offset(kGirdSpace)
                            }
                        }
                        if (inx+1 >= h*(v-1))  && (count%h != 0){
                            if (inx+1 == h*(v-1)+1) {
                                let rmleft = (rect.width*CGFloat(h)-(CGFloat(count%h)*rect.width))/2
                                make.left.equalTo(rect.origin.x+rmleft)
                            }else {
                                make.left.equalTo(visiableVs[inx-1].snp.right).offset(kGirdSpace)
                            }
                        }else {
                            if j == 0 {
                                make.left.equalTo(rect.origin.x)
                            }else {
                                make.left.equalTo(visiableVs[j-1].snp.right).offset(kGirdSpace)
                                
                            }
                        }
                        
                    }
                }
            }
        }
    }
}


extension TCGirdView:TCVideoViewDelegate {
    func trtcVideo_mute(view: TCVideoView, btn: ZHButton) {
        let index = self.infoList.firstIndex { (info) -> Bool in
            return (view.data?.userId==info.userId)
        }
        if self.touchDelegate != nil && (index != nil) {
            self.touchDelegate?.trtcGird_mute(girdView: self, row: index!, view: view, btn: btn)
        }
    }
    
    func trtcVideo_more(view: TCVideoView, btn: ZHButton) {
        let index = self.infoList.firstIndex { (info) -> Bool in
            return (view.data?.userId==info.userId)
        }
        if self.touchDelegate != nil && (index != nil) {
            self.touchDelegate?.trtcGird_more(girdView: self, row: index!, view: view, btn: btn)
        }
    }
    
    func trtcVideo_handUp(view: TCVideoView, icon: KIcon) {
        let index = self.infoList.firstIndex { (info) -> Bool in
            return (view.data?.userId==info.userId)
        }
        if self.touchDelegate != nil && (index != nil) {
            self.touchDelegate?.trtcGird_hand(girdView: self, row: index!, view: view, icon: icon)
        }
    }
    
    func trtcVideo_onClick(view: TCVideoView, event: NSEvent) {
        let index = self.infoList.firstIndex { (info) -> Bool in
            return (view.data?.userId==info.userId)
        }
        if self.touchDelegate != nil && (index != nil) {
            self.touchDelegate?.trtcGird_onClick(girdView: self, row: index!, view: view, event: event)
        }
    }
    
    func trtcVideo_donbleClick(view: TCVideoView, event: NSEvent) {
        let index = self.infoList.firstIndex { (info) -> Bool in
            return (view.data?.userId==info.userId)
        }
        if self.touchDelegate != nil && (index != nil) {
            self.touchDelegate?.trtcGird_donbleClick(girdView: self, row: index!, view: view, event: event)
        }
        
    }
    
    func trtcVideo_mouseEnter(view: TCVideoView) {
        let index = self.infoList.firstIndex { (info) -> Bool in
            return (view.data?.userId==info.userId)
        }
        if self.touchDelegate != nil && (index != nil) {
            self.touchDelegate?.trtcGird_mouseEnter(girdView: self, row: index!, view: view)
        }
    }
    
    func trtcVideo_mouseExit(view: TCVideoView) {
        let index = self.infoList.firstIndex { (info) -> Bool in
            return (view.data?.userId==info.userId)
        }
        if self.touchDelegate != nil && (index != nil) {
            self.touchDelegate?.trtcGird_mouseExit(girdView: self, row: index!, view: view)
        }
    }
    
}
